<?php
/**
 * 微信服务端api
 * curl逻辑基类
 * 函数验证，过程逻辑验证
 */
namespace App\Services;

use App\Models\DahuaTokenModel;
use App\Models\PetsModel;
use Exception;

class CurlBasiceService extends CommonService
{
    const URL_BASE = 'https://qyapi.weixin.qq.com';

    /**
     * 拼接url
     * @param string $queryArgs
     * @return string
     */
    static public function MakeUrl(string $queryArgs) : string
    {
        $base = self::URL_BASE;
        if (substr($queryArgs, 0, 1) === "/")
            return $base . $queryArgs;
        return $base . "/" . $queryArgs;
    }

    /**
     * get请求 curl
     * @param $url
     * @return bool|string
     * @throws Exception
     */
    static public function httpGet($url, $header = [])
    {
        //判断curl_init函数是否存在
        self::__checkDeps();
        $ch = curl_init();

        //检验是否是https
        self::__setSSLOpts($ch, $url);

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        if (!empty($header)){
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        }

        //校验返回结果
        return self::__exec($ch);
    }

    /**
     * post请求 参数处理
     * @param $arr
     * @return string
     */
    static public function Array2Json($arr) : string
    {
        $parts = array ();
        $is_list = false;
        $keys = array_keys ( $arr );
        $max_length = count ( $arr ) - 1;
        if (($keys [0] === 0) && ($keys [$max_length] === $max_length )) {
            $is_list = true;
            for($i = 0; $i < count ( $keys ); $i ++) {
                if ($i != $keys [$i]) {
                    $is_list = false;
                    break;
                }
            }
        }
        foreach ( $arr as $key => $value ) {
            if (is_array ( $value )) {
                if ($is_list)
                    $parts [] = self::array2Json ( $value );
                else
                    $parts [] = '"' . $key . '":' . self::array2Json ( $value );
            } else {
                $str = '';
                if (! $is_list)
                    $str = '"' . $key . '":';
                if (!is_string ( $value ) && is_numeric ( $value ) && $value<2000000000)
                    $str .= $value;
                elseif ($value === false)
                    $str .= 'false';
                elseif ($value === true)
                    $str .= 'true';
                else
                    $str .= '"' .addcslashes($value, "\\\"\n\r\t/"). '"';
                $parts[] = $str;
            }
        }
        $json = implode ( ',', $parts );
        if ($is_list)
            return '[' . $json . ']';
        return '{' . $json . '}';
    }

    /**
     * post请求 curl
     */
    static public function httpPost(string $url, $postData, $header='')
    {
        //判断curl_init函数是否存在
        self::__checkDeps();
        $ch = curl_init();

        //检验是否是https
        self::__setSSLOpts($ch, $url);

        curl_setopt($ch, CURLOPT_POST, 1);

        curl_setopt($ch, CURLOPT_URL, $url);

        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        if (!empty($header)){
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(

                'Content-Type: application/json; charset=utf-8',

                'Content-Length: ' . strlen($postData),

                'Authorization: Bearer ' . $header
                )
            );
        }else{
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(

                'Content-Type: application/json; charset=utf-8',

                'Content-Length: ' . strlen($postData),

                 )
            );
        }

        $res = curl_exec($ch); //已经获取到内容,没有输出到页面上.
        curl_close($ch);

        return json_decode($res, true);
    }

    /**
     * post请求 curl
     */
    static public function httpPostChat(string $url, $postData, $header='')
    {
        //判断curl_init函数是否存在
        self::__checkDeps();
        $ch = curl_init();

        //检验是否是https
        self::__setSSLOpts($ch, $url);

        curl_setopt($ch, CURLOPT_POST, 1);

        curl_setopt($ch, CURLOPT_URL, $url);

        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'Accept:application/json',
                'Content-Type:application/json; charset=utf-8',
                'User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
                'Authorization:'.$header
            )
        );

        $res = curl_exec($ch); //已经获取到内容,没有输出到页面上.
        curl_close($ch);

        return json_decode($res, true);
    }

    public function handleSign($orderid, $mchid, $noncestr){
        $apiurl = 'https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/'.$orderid.'?mchid='.$mchid;
        $urlarr = parse_url($apiurl);
        $url = $urlarr['path'].(!empty($urlarr['query'])?'?'.$urlarr['query']:'');
        $time = time();
        $jsonData = '';
        $xlid = '4F3AA86C2902606D0A79FFF270E1E53A9753AA3E';

//        $str = "POST"."\n".$url."\n".$time."\n".$noncestr."\n".$jsonData."\n";

        $str = "POST"."\n".
            $url."\n".
            $time."\n".
            $noncestr."\n".
            $jsonData."\n";

        $signHead = $this->getSign($str);
        $schema = 'WECHATPAY2-SHA256-RSA2048';
        $token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
            $mchid, $noncestr, $time, $xlid, $signHead);
        return [$schema, $token];

    }

    public function getSign($content)
    {
        $apiclient_key = public_path() . '/chat/apiclient_key.pem';
        $binary_signature = "";
        $privateKey = file_get_contents($apiclient_key);
        openssl_sign($content, $binary_signature, $privateKey, 'sha256WithRSAEncryption');
        return base64_encode($binary_signature);
    }

    /**
     * 判断curl_init函数是否存在
     * @return void
     * @throws Exception
     */
    static private function __checkDeps()
    {
        if (!function_exists("curl_init")) {
            throw new Exception("missing curl extend");
        }
    }

    /**
     * 检验是否是https
     * @param $ch
     * @param $url
     * @return void
     */
    static private function __setSSLOpts($ch, $url)
    {
        if (stripos($url,"https://") !== false) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($ch, CURLOPT_SSLVERSION, 1);
        }
    }

    /**
     * 校验返回结果code
     * @param $ch
     * @return bool|string
     * @throws Exception
     */
    static private function __exec($ch)
    {
        $output = curl_exec($ch);
        $status = curl_getinfo($ch);
        curl_close($ch);

        if ($output === false) {
            throw new Exception("network error");
        }

//        $output_json = json_decode($output, true);
//        if (empty($output_json['openid'])) {
//
//            throw new Exception(
//                "code is error, relation 刘博文. code ". intval($output_json["errcode"]) . ", unexpected http errmsg ". intval($output_json["errmsg"]));
//        }

        return $output;
    }

    /**
     * @param $id
     * @return mixed|string
     */
    static public function getFlv($id)
    {
        $pets = PetsModel::getSingle(['id'=> $id]);
        if (empty($pets['camera_type'])){
            return '';
        }

        $result = DahuaTokenModel::getSingle();

        unset($data);
        $header = $result['token'];
        $data['deviceId'] = $pets['camera_type'] ?? '';
        $data['channelId'] = $pets['camera_port'] ?? 0;
        $result1 = self::httpPost('https://www.cloud-dahua.com/gateway/videobussiness/api/queryFlvLive', json_encode($data), $header);
        if ($result1['code'] <> 200){
            //创建通道
            unset($data);
            $data['deviceId'] = $pets['camera_type'] ?? '';
            $data['channelId'] = $pets['camera_port'] ?? 0;
            $result2 = self::httpPost('https://www.cloud-dahua.com/gateway/videobussiness/api/createFlvLive', json_encode($data), $header);

            if (!empty($result2['data']['flv'])){
                return $result2['data']['flv'];

            }
        }else{
            return $result1['data']['flv'];

        }

        return '';

    }
}
